package com.zheng.russiaRec.model 
{
	import com.zheng.utils.DebugTrace;
	import com.zheng.russiaRec.model.utils.U_ArrConcat;
	import com.zheng.russiaRec.model.utils.U_CopyRecArr;
	import com.zheng.russiaRec.model.utils.U_DelArrFromTargetArr;
	import com.zheng.russiaRec.model.utils.U_DisposeArr;
	import com.zheng.russiaRec.model.utils.U_GetInfoFromArr;
	import com.zheng.russiaRec.model.utils.U_GetRecVoFromArr;
	import com.zheng.russiaRec.model.vo.VO_Checkerboard;
	
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.proxy.Proxy;

	/**
	 * @describe  	棋盘proxy
	 * @author  	Mr.zheng
	 * @website 	http://blog.sina.com.cn/zihua2007
	 * @time		... 
	 */
	public class P_Checkerboard extends Proxy implements IProxy
	{
		public static const NAME:String = "P_NAME_CHECKERBOAR";
		//moveStatus值
		public static const ASTRICT_MOVE:int=1;
		public static const MOVE_BOTTOM:int=2;
		public static const CAN_MOVE_TO:int=3;
		//userOP向下
		private static const KEY_DOWN:int=Keyboard.DOWN;
		
		//积木触底，触底后就可以开始判断，是否消除忙了的行，和创建新的group
		//积木触底，该值置为true，当检测过是否能够消行之后，置为false
		private var _isToBottom:Boolean = false;
		
		//功能==========================================================
		private var u_delArrFromArr:U_DelArrFromTargetArr;
		private var u_arrConcat:U_ArrConcat;
		private var u_getRecFromArr:U_GetRecVoFromArr;
		private var u_copyRecArr:U_CopyRecArr;
		private var u_disposeArr:U_DisposeArr;
		private var u_getInfocFromArr:U_GetInfoFromArr;
		//===============================================================
		
		//liveGrop代理
		private var lg:P_LiveGroup;
		//fixedGroup代理
		private var fg:P_FixedGroup;
		
		//data.m_checkerboard	棋盘数据
		public function P_Checkerboard(data:Object = null) 
		{
			super(NAME, data);
			u_delArrFromArr = new U_DelArrFromTargetArr();
			u_arrConcat = new U_ArrConcat();
			u_getRecFromArr=new U_GetRecVoFromArr();
			u_copyRecArr = new U_CopyRecArr();
			u_disposeArr = new U_DisposeArr();
			u_getInfocFromArr=new U_GetInfoFromArr();
			
			fg = new P_FixedGroup();
			
			DebugTrace.instance.setMonitorObj(vo);
		}
		/**
		 * 随机获取group数据,创建积木
		 * @return
		 */
		public function createGroup():void {
			lg=new P_LiveGroup();
			lg.liveGroupData;
		}
		/**
		 * 能够创建积木？
		 * 创建的积木是否覆盖住了fixedGroup
		 * @ param arr
		 */
		public function canCreateGroup(arr:Array):Boolean
		{
			var sx:int;
			var sy:int;
			var recVo:Array;
			for (var name:String in liveGroup) 
			{
				recVo=arr[name] as Array;
				sx=recVo[0];
				sy=recVo[1];
				if (isInFixed(sx, sy)) {
					return false;
				}
			}
			return true;
		}
		/**
		 * @param	dx	0表示x方向上不变|1表示右移|-1表示左移
		 * @param	dy	0表示y方向上不变|1表示下移|-1表示上移
		 */
		public function setLiveToGroup(dx:int,dy:int):Array {
			//根据dx，dy计算目的rec的数组
			var temp:Array=new Array();
			var itemArr:Array=[];
			var recVo:Array;
			for (var name:String in liveGroup){
				recVo=liveGroup[name] as Array;
				itemArr = [recVo[0] + dx, recVo[1] + dy];
				temp.push(itemArr);
			}
			return temp;
		}
		/**
		 * 旋转group
		 */
		public function rotationGroup():Array
		{
			return lg.rotationData;
		}
		/**
		 * 清理liveGirdGroup和liveToGroup
		 * 执行：
		 * 1。移动积木
		 * 2。旋转积木
		 */
		public function clearGroup():void {
			u_disposeArr.disposeArr(liveGroup);
			liveGroup = [];
			if(liveToGroup.length>0){
				liveGroup = liveToGroup.concat();
				liveToGroup = [];
			}
		}
		//清除fixedGroup
		public function clearFixedGroup():void
		{
			u_disposeArr.disposeArr(fixedGroup);
			fixedGroup = [];
			if (fixedToGroup.length > 0) {
				fixedGroup = fixedToGroup;
				fixedToGroup = [];
			}
		}
		/**
		 * 指定的arr组成的积木，在棋盘中处于什么位置
		 * @param arr 
		 * @param userOP	用户操作
		 * @return 
		 * 1	表示group被左右边界和上边界限制		
		 * 2	表示group已经触底		
		 * 3	表示能够正常到达目标位置
		 */
		public function getTargetStatus(arr:Array,userOP:int=0):int{
			var moveStatus:int=0;			
			for (var name:String in arr) 
			{
				var sx:int=arr[name][0];
				var sy:int=arr[name][1];
				if (canMoveTo(sx, sy)){
					moveStatus=CAN_MOVE_TO;
					continue;
				}
				if(!isInAround(sx,sy)||!isInUp(sx,sy)){
					moveStatus=ASTRICT_MOVE;
					break;
				}
				if(isPassDown(sx,sy)||isInFixed(sx,sy)){
					if(userOP==KEY_DOWN){
						moveStatus=MOVE_BOTTOM;
						_isToBottom=true;//触底
						break;
					}else{
						moveStatus=ASTRICT_MOVE;
						break;
					}
				}
			}
			return moveStatus;
		}
		/**
		 *  
		 * @param arr		
		 * @param status	
		 * 1	表示group被左右边界和上边界限制		
		 * 2	表示group已经触底		
		 * 3	表示能够正常到达目标位置
		 * 
		 */
		public function dealMoveStatus(arr:Array,status:int):void{
			if(status==ASTRICT_MOVE){
				liveToGroup=liveGroup;
				liveGroup=[];
			}
			if(status==MOVE_BOTTOM){
				fixedGroup=u_arrConcat.concatArr(fixedGroup,liveGroup);
				liveGroup=[];
				_isToBottom=true;//触底
			}
			if(status==CAN_MOVE_TO){
				liveToGroup=arr;
			}
		}
		/**
		 * 有可以删除的行
		 * @return	[删除的对象,删除的行号]
		 */
		public function hasLineFull():Array
		{
			//fixedGridGroup中，所有的行都检查一下，是否有能够删除的行
			//并返回可删除对象
			var minNum:int = fg.getFixedMinLine(vo.cols);
			var tempArr:Array = [];						//所有可消除的行
			var lineArr:Array = [];						//单行
			var numArr:Array = [];						//可消除行的行号
			for (var i:int = minNum; i < vo.cols; i++) 
			{
				lineArr = fg.getFullLine(vo.row,i);
				if (lineArr != null) {
					numArr.push(i);
					tempArr = u_arrConcat.concatArr(tempArr, lineArr);
					lineArr = [];
				}
			}
			if(numArr.length>0){
				fixedToGroup = u_copyRecArr.copyRecArr(fixedGroup);
				u_delArrFromArr.delArrFromTargetArr(fixedToGroup, tempArr);					//删除fixedGroup中的数据
				fg.moveHangRec(fixedToGroup,numArr);									//悬空的rec下落
				return [tempArr,numArr];
			}else {
				return null;
			}
		}
		public function getMinDis():int {
			
			return u_getInfocFromArr.getMinDis(liveGroup,fixedGroup,vo.cols);
		}
		/**
		 *	设置当前移动积木的偏移值 
		 * @param dx
		 * @param dy
		 * 
		 */
		public function setLgOffset(dx:int,dy:int):void{
			lg.sx+=dx;
			lg.sy+=dy;
		}
		public function setLgDirNext():void{
			lg.dir++;
		}
		/**
		 * dir值回退 
		 */
		public function setLgDirBack():void{
			lg.dir--;
		}
		/**
		 * 棋盘的行、列、宽、高 
		 * @return 
		 * 
		 */
		public function getCbRec():Rectangle{
			return new Rectangle(vo.row,vo.cols,vo.w,vo.h);
		}
		public function get vo():VO_Checkerboard {
			return data.vo_checkerboard;
		}
		public function get liveGroup():Array {
			return lg.liveGridGroup;
		}
		public function set liveGroup(value:Array):void{
			lg.liveGridGroup=value;
		}
		public function get liveToGroup():Array {
			return lg.liveToGroup;
		}
		public function set liveToGroup(value:Array):void{
			lg.liveToGroup=value;
		}
		public function set isToBottom(value:Boolean):void{
			_isToBottom=value;
		}
		public function get isToBottom():Boolean{
			return _isToBottom;
		}
		public function set fixedGroup(value:Array):void {
			fg.fixedGridGroup=value;
		}
		public function get fixedGroup():Array {
			return fg.fixedGridGroup;
		}
		public function set fixedToGroup(value:Array):void {
			fg.fixedToGroup=value;
		}
		public function get fixedToGroup():Array {
			return fg.fixedToGroup;
		}
		//私有===============================================================
		/**
		 * 是否能移动到sx,sy
		 * @return
		 */
		private function canMoveTo(sx:int,sy:int):Boolean {
			if (!isInCB(sx, sy)) return false;
			var recVo:Array = u_getRecFromArr.getRecVoFromArr(fixedGroup, sx, sy);
			if (recVo) return false;
			return true;
		}
		/**
		 * 是否在左右边界范围内 
		 * @return 
		 * 
		 */
		private function isInAround(sx:int,sy:int):Boolean{
			if (sx<0||sx>=vo.row)return false;
			return true;
		}
		/**
		 * 是否超出棋盘的上面区域 
		 * @return 
		 * 
		 */
		private function isInUp(sx:int,sy:int):Boolean{
			if(sy<0)return false;
			return true;
		}
		/**
		 * 是否超出棋盘的底部区域 
		 * @return 
		 * 
		 */
		private function isPassDown(sx:int,sy:int):Boolean{
			if(sy>=vo.cols)return true;
			return false;
		}
		/**
		 * 是否进入了固定积木范围
		 * @return 
		 * 
		 */
		private function isInFixed(sx:int,sy:int):Boolean{
			var recVo:Array = u_getRecFromArr.getRecVoFromArr(fixedGroup, sx, sy);
			if (recVo) return true;
			return false;
		}
		/**
		 * 是否在棋盘范围内
		 * @return
		 */
		private function isInCB(sx:int,sy:int):Boolean {
			if (sx<0||sx>=vo.row)return false;
			if (sy<0||sy>=vo.cols)return false;
			return true;
		}
		/**
		 * 消除行之后，悬空的积木 
		 * 
		 */
		private function getHangFromFixed():Array{
			return null;
		}
	}
}